package com.tsx.template.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import com.tsx.template.common.vo.Result;
import com.tsx.template.common.properties.CustomFileProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Objects;
import java.util.UUID;

@RestController
@RequestMapping("/file")
@RequiredArgsConstructor
@Slf4j
public class FileController {
    final CustomFileProperties customFileProperties;
    final Environment env;

    @PostMapping("/upload")
    public Result<String> upload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return Result.error("上传的文件为空");
        }
        // 获取文件名
        String originalFilename = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
        // 生成一个唯一的文件名，防止文件名冲突
        String fileName = UUID.randomUUID() + "_" + originalFilename;
        try {
            File savePath = new File(customFileProperties.getPath());
            if (!savePath.exists()) {
                savePath.mkdir();
            }
            file.transferTo(new File(savePath + File.separator + fileName));
            return Result.data("http://localhost:" + env.getProperty("server.port") + "/file/download/" + fileName);
        } catch (IOException e) {
            log.error("文件上传失败", e);
            return Result.error("文件上传失败");
        }
    }

    @GetMapping("/download/{fileName}")
    @SaIgnore
    public Result<?> downloadFile(@PathVariable String fileName, HttpServletResponse response) {
        // 构造文件路径
        String filePath = customFileProperties.getPath() + File.separator + fileName;
        File file = new File(filePath);

        // 检查文件是否存在
        if (!file.exists()) {
            return Result.error("文件不存在");
        }

        // 返回文件
        // 将文件数据通过输出流写入响应
        try (FileInputStream fis = new FileInputStream(file);
             OutputStream outputStream = response.getOutputStream()) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
        } catch (IOException e) {
            log.error("文件下载失败", e);
            return Result.error("文件下载失败");
        }
        return Result.msg("文件下载成功");
    }
}
